package com.domainlanguage.internal;

import com.domainlanguage.base.Ratio;
import com.domainlanguage.money.MoneyTimeRate;
import com.domainlanguage.time.*;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Currency;

/**
 * Workaround for accessing non-accessible fields in TimeAndMoney 0.5.1.
 * 
 */
public class FieldReaderUtils {

    public static TimeRate readTimeRate(MoneyTimeRate moneyTimeRate) {
        return (TimeRate) readField(moneyTimeRate, "timeRate");
    }

    public static Currency readCurrency(MoneyTimeRate moneyTimeRate) {
        return (Currency) readField(moneyTimeRate, "currency");
    }

    public static BigDecimal readQuantity(TimeRate timeRate) {
        return (BigDecimal) readField(timeRate, "quantity");
    }

    public static Duration readUnit(TimeRate timeRate) {
        return (Duration) readField(timeRate, "unit");
    }

    public static CalendarDate readDate(CalendarMinute calendarMinute) {
        return (CalendarDate) readField(calendarMinute, "date");
    }

    public static TimeOfDay readTime(CalendarMinute calendarMinute) {
        return (TimeOfDay) readField(calendarMinute, "time");
    }

    public static BigDecimal readNumerator(Ratio ratio) {
        return (BigDecimal) readField(ratio, "numerator");
    }

    public static BigDecimal readDenominator(Ratio ratio) {
        return (BigDecimal) readField(ratio, "denominator");
    }

    private static Object readField(Object o, String fieldName) {
        try {
            Field field = o.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(o);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private FieldReaderUtils() {
    }
}
